﻿#include "TcpThread.h"
#include "TcpClient.h"

using namespace FCMiddleware;

TcpThread::TcpThread(Depacker* depacker, const QString& hostName, unsigned short hostPort, QObject *parent)
{
	_connected = false;
	_hostName = hostName;
	_hostPort = hostPort;

    _depacker = depacker;
    _tcpClient = NULL;

	_isRunning = false;
	_running = false;
}

TcpThread::~TcpThread()
{
}

void TcpThread::setHost(const QString& hostName, unsigned short hostPort)
{
	_hostName = hostName;
	_hostPort = hostPort;
}

void TcpThread::host(QString& hostName, unsigned short& hostPort)
{
	hostName = _hostName;
	hostPort = _hostPort;
}

void TcpThread::run()
{
	_isRunning = true;
	bool runable = true;

	bool reconnect = false;
    int err;

    emit stateChanged(ThreadStateType_Running, 0);

	while (1)
	{
		//未连接时进行连接
		while (!_connected)
		{
			_runLocker.lock();
			runable = _running;
			_runLocker.unlock();

			if (!runable)
				break;

			if (reconnect)
                emit stateChanged(ThreadStateType_Reopening, 0);
            else emit stateChanged(ThreadStateType_Opening, 0);

            _tcpClient = new TcpClient(_hostName, _hostPort);
            bool bret = _tcpClient->connectToServer(2, &err);
			if (!bret) //未连接时重新连接
			{
                delete _tcpClient;
                _tcpClient = NULL;
                emit stateChanged(ThreadStateType_OpenFailed, err);
				reconnect = true;

                if(err == QAbstractSocket::NetworkError)
                    msleep(5000);
				continue;
			}
			else
			{
				_connected = true;
                emit stateChanged(ThreadStateType_Opened, 0);
				break;
			}
		}

        _depacker->clear();
        unsigned int size;
        unsigned char* buf;
        int ret;

        while (1)
        {
            _runLocker.lock();
            runable = _running;
            _runLocker.unlock();

            if (!runable)
                break;

            if (!sendPacket())
            {
                _tcpClient->destory();
                _connected = false;
                break;
            }

            buf = _depacker->buf(&size);
            ret = _tcpClient->recv(buf, size, &err);
            if (ret == -1)
            {
                emit stateChanged(ThreadStateType_ReadFailed, err);
                _tcpClient->destory();
                _connected = false;
                break;
            }
            else if (ret == 0)
                continue;
            else _depacker->push(ret);

            if (!recvPacket())
                break;
        }
    }

    if (_tcpClient != NULL)
    {
        _tcpClient->destory();
        _connected = false;

        emit stateChanged(ThreadStateType_Close, 0);
    }

    emit stateChanged(ThreadStateType_Quit, 0);
    _isRunning = false;
    return;
}

void TcpThread::startServer()
{
	_running = true;
	start(QThread::TimeCriticalPriority);
}

void TcpThread::stopServer()
{
	_runLocker.lock();
	_running = false;
	_runLocker.unlock();
	while (_isRunning);
}

bool TcpThread::sendPacket()
{
    Q_ASSERT(_tcpClient != NULL);

    return true;
}

bool TcpThread::recvPacket()
{
    return true;
}
